from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.contrib.auth import login, logout, authenticate
from django.template import RequestContext
from django.template.loader import get_template
from django.shortcuts import render_to_response
from django.middleware.csrf import get_token
from django.core.mail import send_mail
from django.db.models import Q

#Note that on the webfaction server, we don't need "gardens." on the next two lines
#Because of the differenece, wrap the import statements in a try, except block.
try:
	from forms import *
	from models import *
except:
	from gardens.forms import *
	from gardens.models import *

# CALC page at '/calc/'
def calc_page(request):
	# if the request has an id such as calc/?garden_id=17, then use that.
	# The page will be loaded with either a real garden_id, 
	# or -999 for a newly created garden
	# we won't create a record for it in the database until the user saves it.
	# Note that we are no longer trying to make this do dual service to track anonymous vs. authenticated users,
	# as it was becoming too complicated, and Django has built-in functions that handle this nicely. 
	
	user = request.user
	
	# Figure out if the user is a new user
	# (Either this is his first garden, or 
	
	if user.is_anonymous():
		new_user = 1
	else:
		num_gardens = len(user.garden_set.all())
		if num_gardens == 0:
			new_user = 1
		else:
			new_user = 0
	
	try:
		garden_id = request.POST['garden_id']
		if garden_id == "#" or garden_id =="-999":
			return render_to_response('calc.html', { 'garden_id': -999, 'user': request.user, 'new_user': new_user })
	except:
		return render_to_response('calc.html', {'garden_id': -999, 'user': request.user, 'new_user': new_user })
	
	#todo: check to make sure the garden is in the database
	# if it is not, re-direct the user to a page that says, "Can't find that page," with a link to re-direct home.
	
	#todo: check to make sure the user is authorized to view this garden...
	# How would this even happen? They could be a hacker that is adding POST data using some kind of browser tools.
	# (Who the heck would do this? It's not like we're collecting credit card numbers...)
	# Or, they could have loaded the Index page, then cleared their cookies, then clicked the launch garden link.
	# This would be a problem, because the
	
	# The following code should take care of both of those things??
	#todo: wrap this in a try...except?
	
	
	# Don't bother checking for users that are "staff"
	if (not user.is_staff):
		#deny access to saved gardens to users who are not logged in
		if (not user.is_authenticated()):
			return HttpResponseRedirect('../denied/')
		
		#deny access to gardens that the user does not own
		garden = Garden.objects.get(id=int(garden_id))
		if garden.user <> user:
			return HttpResponseRedirect('../denied/')
	
	return render_to_response('calc.html', {'garden_id': garden_id, 'user': request.user, 'new_user': new_user})

# HOME page at '/'
def main_page(request):
	user = request.user
	
	#check whether the user has a temporary garden that he's been working on before he logged in
	if request.COOKIES.has_key('temp_garden'):
		temp_garden = request.COOKIES[ 'temp_garden' ]
		mygarden = Garden.objects.get(id=temp_garden)
		if user.is_authenticated():
			mygarden.user = user
			mygarden.save()
	
	try:
		#for users that are staff, load ALL of the gardens that exist (paginate them? future)
		if user.is_staff:
			gardens = Garden.objects.all()
		else:
			gardens = user.garden_set.all()
	except:
			gardens = {}
	
	response = render_to_response('index.html', {'user': request.user, 'gardens': gardens, 'csrf_token': get_token(request) })
	response.delete_cookie('temp_garden')
	return response

# DELETE my account page
def delete_page(request):
	#This is the page that deletes a user's account,
	#And all of the gardens he has ever created (!!!)
	#(Or do we want to keep them in the database to be able to view the history???)
	
	#if the page is loaded by a simple GET request, it will show the "Do you really want to?" page
	
	#if the user has clicked the delete button, that means they submitted the form, and we can go ahead and REALLY delete
	
	
	if (not request.user.is_authenticated()):
		return HttpResponseRedirect('../login/')
	
	if request.method == 'POST':
		#This means the user has clicked the button to really do it!
		user = request.user
		gardens = user.garden_set.all()
		gardens.delete()
		user.delete()
		
		response = render_to_response('registration/delete_account_done.html')
		
	else:
		#GET (The user is just loading the page for the first time)
		response = render_to_response('registration/delete_account.html', {'user': request.user,  'csrf_token': get_token(request)} )
	
	return response

# LOGOUT page
def logout_page(request):
	logout(request)
	return HttpResponseRedirect('/')

# ACCOUNT Management page
def account_page(request):
	# For now, allows the user to change their email address.
	# (and it could allow to change name, address, phone number, etc. if we add these fields to our user db).

	# Redirect guests to login page.
	if (not request.user.is_authenticated()):
		return HttpResponseRedirect('../login/')
	
	# if in response to a form submission
	if request.method == 'POST':
		form = AccountManagementForm(request.POST)
		
		if form.is_valid():
			user = request.user
			user.email = form.cleaned_data['email_new']
			user.save()
			response = HttpResponseRedirect('/account/updated/')
			return response
	
	# Give the user a blank acct. mgmt. form to fill out.
	else:
		user = request.user
		form = AccountManagementForm({'email_old': user.email, 'email_new': user.email})


	variables = RequestContext(request, {'form': form })
	
	return render_to_response('registration/account.html', variables)

# Register Page
def register_page(request):
	# This function returns the empty form upon a GET request
	# or saves the user's registration data
	if request.method == 'POST':
		form = RegistrationForm(request.POST)
		
		if form.is_valid():
			user = User.objects.create_user(
				username=form.cleaned_data['username'],
				password=form.cleaned_data['password1'],
				email=form.cleaned_data['email']
				)
				
			#check whether the user started entering garden data before registering
			if request.COOKIES.has_key('temp_garden'):
				temp_garden = request.COOKIES[ 'temp_garden' ]
				mygarden = Garden.objects.get(id=temp_garden)
				mygarden.user = user
				mygarden.save()
				
			#Go ahead and log the user in. No reason to make them login afterwards
			new_user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password1'])
			login(request, new_user)
			
			#Send the new user a welcome email
			send_mail('Thanks for registering at RiverFriendly.com', msg % new_user.username, 'admin@riverfriendly.com', ['%s' % new_user.email], fail_silently=True)
			
			response = HttpResponseRedirect('/register/success/')
			response.delete_cookie('temp_garden')
			return response
	else:
		# A normal page request (not in response to a form submission)
		
		# If the user is already logged in, redirect them to the account management page.
		user = request.user
		if user.is_authenticated():
			return HttpResponseRedirect('../account/')
			
		form = RegistrationForm()

	variables = RequestContext(request, {'form': form })
	
	return render_to_response('registration/register.html', variables)

# DUPLICATE garden AJAX handler
def duplicater_ajax(request):
	from django.utils import simplejson as json
	
	#duplicates a garden
	garden_id = request.POST['garden_id']
	garden_name = request.POST['garden_name']
	
	try:
		#pull information from old garden
		old_garden = Garden.objects.get(id=garden_id)
		
		#replace the garden name in the data field
		#(This was not reliable, e.g. when the garden name was an empty string)
		#data = old_garden.data
		#data = data.replace(old_garden.name, garden_name)
		
		#It is redundant, but for the sake of convenience, we are storing the garden name in two places.
		#First, it is a part of the JSON string "data"; it is also stored in it's own field.
		#This only becomes an issue when duplicating a garden: the data in the JSON string data 
		#becomes out of date. So we have to unpack it, modify it, then re-pack it...
		data_obj = json.loads(old_garden.data)
		data_obj["garden_name"] = garden_name
		data_str = json.dumps(data_obj, ensure_ascii=False)
		
		#create a new, empty garden
		newgarden = Garden.objects.create(user=old_garden.user)

		#Name supplied by the user
		newgarden.name = garden_name
		
		#Data is the JSON string that we just encoded
		newgarden.data = data_str
		
		#Everything else is cloned!
		newgarden.area_total = old_garden.area_total
		newgarden.user_water = old_garden.user_water
		newgarden.user_waste = old_garden.user_waste
		newgarden.user_emiss = old_garden.user_emiss
		newgarden.conv_water = old_garden.conv_water
		newgarden.conv_waste = old_garden.conv_waste
		newgarden.conv_emiss = old_garden.conv_emiss
		newgarden.qualified  = old_garden.qualified
		
		newgarden.save()

		return HttpResponse('{"duplicated": %s}' % newgarden.id,  mimetype="application/json")
	except:
		return HttpResponse('{"duplicated": false}', mimetype="application/json")

# DELETE garden AJAX handler
def deleter_ajax(request):
	#deletes a garden
	garden_id = request.POST['garden_id']
	try:
		mygarden = Garden.objects.get(id=garden_id)
		mygarden.delete()
		
		#is this how to delete a database row?
		return HttpResponse('{"deleted": true}',  mimetype="application/json")
		
	except:
		return HttpResponse('{"deleted": false}', mimetype="application/json")

# LOAD an existing garden AJAX handler
def loader_ajax(request):
	#returns the JSON string with the data for the calculator page stored in a previous visit
	#try:
	garden_id = request.POST['garden_id']
	try:
		mygarden = Garden.objects.get(id=garden_id)
		data = mygarden.data
		return HttpResponse(data, mimetype="application/json")
	
	except:
		return HttpResponse('{"garden_id":-999}', mimetype="application/json")

# SAVE a garden AJAX handler
def saver_ajax(request):
	#put the JSON string with the calculator data into the database
	
	garden_id = request.POST['garden_id']
	data = request.POST['data']
	name = request.POST['garden_name']
	area_total = int(request.POST['area_total'])
	user_water = int(request.POST['user_water'])
	user_waste = int(request.POST['user_waste'])
	user_emiss = int(request.POST['user_emiss'])
	conv_water = int(request.POST['conv_water'])
	conv_waste = int(request.POST['conv_waste'])
	conv_emiss = int(request.POST['conv_emiss'])
	qualified = (request.POST['qualified' ] == 'true' )
	
	user = request.user
	
	# How to handle users who are not logged in?
	if not user.is_authenticated():
		
		# since the user is not logged in, 
		# temporarily store the garden under the username 'orphans'
		# we will send the garden_id back in a cookie, and then we can re-associate this garden with a proper useridid
		# if they ever register

		user = User.objects.get(username="orphans")
		mygarden = Garden.objects.create(data=data, name=name, user=user, area_total=area_total, user_water=user_water, user_waste=user_waste, user_emiss=user_emiss, conv_water=conv_water, conv_waste=conv_waste, conv_emiss=conv_emiss, qualified=qualified)
		
		#get the new garden_id
		garden_id = mygarden.id
		
		#set a cookie in user's browser (for length of session only) to hold garden_id
		#then, once the user IS logged in (after they log in or register, we will check for the presence of this cookie, and 
		#associate the garden with this user (probably a klugy way to do this, but it was about the best I could figure out in a hurry)
		response = HttpResponse('{"saved": true, "temp_user": true, "garden_id": %s}' % garden_id, mimetype="application/json")
		response.set_cookie('temp_garden', garden_id)
		
		return response
		
		
	# If the garden_id = -999 that means that it has not yet been saved.
	
	if garden_id == '-999':
		
		try:
			#insert a new row into the database,
			user = request.user
			mygarden = Garden.objects.create(data=data, name=name, user=user, area_total=area_total, user_water=user_water, user_waste=user_waste, user_emiss=user_emiss, conv_water=conv_water, conv_waste=conv_waste, conv_emiss=conv_emiss, qualified=qualified)
			
			#figure out what the id of the new garden is,
			#return this to the webpage so that it can be used in the future.
			garden_id = mygarden.id
			return HttpResponse('{"saved": true, "garden_id": %s}' % garden_id, mimetype="application/json")
			
		except:
			return HttpResponse('{"saved": false, "error": true}', mimetype="application/json")
	else:
		try:
			mygarden = Garden.objects.get(id=garden_id)
			mygarden.data = data
			mygarden.name = name
			mygarden.area_total = area_total
			mygarden.user_water = user_water
			mygarden.user_waste = user_waste
			mygarden.user_emiss = user_emiss
			mygarden.conv_water = conv_water
			mygarden.conv_waste = conv_waste
			mygarden.conv_emiss = conv_emiss
			mygarden.qualified  = qualified
		
			mygarden.save()
			
			return HttpResponse('{"saved":true}', mimetype="application/json")
	
		except:
			return HttpResponse('{"saved":false}', mimetype="application/json")

# LOAD the plants to the Individual Plant Selector AJAX handler
def plant_loader_ajax(request):
	water = request.POST['plant_water_use']
	variety = request.POST['plant_variety']
	search = request.POST['plant_search']
	
	if len(search) > 0:
		q1 = Q(latin__contains=search) | Q(common__contains=search)
	else:
		q1 = Q()
		
	if len(water) > 0:
		q2 = Q(water=water)
	else:
		q2 = Q()
		
	if len(variety) > 0:
		q3 = Q(variety__contains=variety)
	else:
		q3 = Q()
		
	try:
		# TODO: convert the variety field to a LIKE condition
		selected_plants = Plant.objects.filter(q1, q2, q3)
		return render_to_response('plants.html', {"selected_plants": selected_plants})
	
	except:
		#if some kind of error occured (?)
		return HttpResponse('{"selected":false}', mimetype="application/json")

# LOAD a photo for the individual Plant Selector (via AJAX)
def photo_loader_ajax(request):
	plant_id = request.POST['plant_id']
	p = Plant.objects.get(id=plant_id)
	
	try:
		photo = p.photo
		return render_to_response('photos.html', {"photo": photo} )
	except:
		return HttpResponse('<img src="/site_media/photos/none.jpg" width="300" height="200" alt="No photo available" />', mimetype='text/html')


# Email message text (setting it up as a global variable) to be used by the registration routine
msg = """
Thank you for registering as a user at riverfriendly.com.

Your username is %s.

We hope you find the site useful and welcome your feedback.

Best regards,

The River Friendly Team, 
Sacramento County

"""
